using System.Data.Common;
using Dapper.Extensions.Configuration;
using Dapper.Extensions.Hooks;
using Microsoft.Extensions.Logging;

namespace Dapper.Extensions
{
	internal class LoggingHook<T> : ISqlHooks<T>
	{
		private readonly ILogger _logger;
		private readonly DbLoggingConfiguration _config;
		private readonly Func<DbConnection, object> _connectionProjector;

		public LoggingHook(ILogger logger, DbLoggingConfiguration config)
		{
			_logger = logger;
			_config = config;
			_connectionProjector = _config.ConnectionProjector ?? (_ => Empty.Object);
		}

		public void ConnectionOpened(DbConnection connection, T context, long elapsedMs) => 
			_logger.Log(
				_config.LogLevel, 
				_config.OpenConnectionMessage,
				elapsedMs,
				context,
				_connectionProjector(connection));

		public void ConnectionClosed(DbConnection connection, T context, long elapsedMs) => 
			_logger.Log(
				_config.LogLevel, 
				_config.CloseConnectionMessage, 
				elapsedMs,
				context,
				_connectionProjector(connection));

		public void CommandExecuted(DbCommand command, T context, long elapsedMs) =>
			_logger.Log(
				_config.LogLevel, 
				_config.ExecuteQueryMessage, 
				command.CommandText,
				command.GetSqlParameters(hideValues: !_config.LogSensitiveData),
				elapsedMs,
				context,
				_connectionProjector(command.Connection!));
	}
}
